package pers.goetboy.common.vaild;

import lombok.SneakyThrows;
import org.apache.commons.lang3.time.DateUtils;
import pers.goetboy.common.exception.BaseCommonException;
import pers.goetboy.common.utils.LocalDateTimeUtils;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.time.*;
import java.util.Date;

/**
 * CheckTimeInterval 校验类
 *
 * @author goetb
 * @see CheckTimeInterval
 */
public class DateTimeCompValidator implements ConstraintValidator<DateTimeComp, Object> {
    private String dateTime;
    private CheckTimeInterval.Exp exp;

    @Override
    public void initialize(DateTimeComp constraintAnnotation) {
        dateTime = constraintAnnotation.dateTime();
        exp = constraintAnnotation.exp();
    }

    @SneakyThrows
    @Override
    public boolean isValid(Object value, ConstraintValidatorContext context) {
        if (value == null) {
            return true;
        }
        return compare(toLocalDateTime(value), LocalDateTimeUtils.parse(dateTime));
    }


    private LocalDateTime toLocalDateTime(Object time) {
        if (time instanceof Date) {
            Instant instant = ((Date) time).toInstant();
            ZoneId zoneId = ZoneId.systemDefault();
            return instant.atZone(zoneId).toLocalDateTime();
        } else if (time instanceof LocalTime) {
            return LocalDateTime.of(LocalDate.MAX, ((LocalTime) time));
        } else if (time instanceof LocalDate) {
            return LocalDateTime.of(((LocalDate) time), LocalTime.MIN);
        } else if (time instanceof LocalDateTime) {
            return ((LocalDateTime) time);
        }
        throw new BaseCommonException("不支持此种类型的日期校验");
    }

    private boolean compare(LocalDateTime t1, LocalDateTime t2) {
        switch (exp) {
            case GREATER:
                return t1.isAfter(t2);
            case GREATER_OR_EQUAL:
                return t1.isAfter(t2) || t1.isEqual(t2);
            case LESS:
                return t1.isBefore(t2);
            case LESS_OR_EQUAL:
                return t1.isBefore(t2) || t1.isEqual(t2);
            default:
                throw new BaseCommonException("没有找到校验方式");
        }


    }
}
